var conf = require('./config').media;
var net = require('net');
var fs = require('fs');
var path = require('path');
var request = require('request');
var err = require('./my_modules/error');
var ffmpeg = require('fluent-ffmpeg');

var uploadingFiles = {};
var liveChannels = {};
//创建TCP客户端
var slave = new net.Socket();
slave.setEncoding('utf8');
var getConnect = function(){
    slave.connect(conf.tcpServerPort, conf.tcpServerHost, function () {
        console.log('已连接到服务器');
        slave.write('Slave');
    });
};
slave.on('data',function (data) {
    var command = data.toString();
    try{
        command = JSON.parse(command);
    }catch(e){
        slave.write(JSON.stringify({error:1, errmsg: 'Command is not JSON.'}));
        return;
    }
    if(command.command === 'list') {
        var files = [],
            type = command.type || 'img',
            scape = command.scape || '+';
        var search = function (dir) {
            var names = fs.readdirSync(dir);
            names.forEach(function (_name) {
                var state = fs.statSync(path.join(dir,_name));
                if(state.isDirectory()){
                    search(path.join(dir,_name));
                }else{
                    if(type === fileType(_name) && _name.indexOf(scape) === -1 ){
                        files.push({
                            name: _name,
                            size: byteToStr(state.size),
                            ctime: state.ctime,
                            dir: dir.split('files')[1]
                        })
                    }
                }
            })
        };
        search(path.resolve('./files'));
        var list= files.slice(command.offset, command.offset+command.limit);
        console.log('Find a '+files.length+' list');
        slave.write(JSON.stringify({
            count: files.length,
            rows: list
        }));
    }
    else if(command.command === 'picture') {
        if(!command.dir || !command.name) {
            slave.write(JSON.stringify(err.paraErr));
            return;
        }
        command.dir = command.dir.replace(/\,/g,'/');
        var names = fs.readdirSync(path.resolve('./files'+command.dir));
        var uploadFiles = function(list){
            if(!list || list.length <= 0) return;
            var name = list.shift();
            if(name.indexOf(command.name) >= 0 && fileType(name) === 'img' && !uploadingFiles[command.name]) {
                uploadingFiles[command.name] = true;
                console.log('Uploading '+command.name);
                request({
                    method: 'POST',
                    url: 'http://'+conf.clientHost+':'+conf.clientHttp+'/live',
                    formData: {
                        filename: name,
                        file: fs.createReadStream(path.resolve('./files'+command.dir+'/'+name))
                    }
                }, function(e){
                    if(e) console.log(e);
                    delete uploadingFiles[command.name];
                    console.log('Uploaded  '+command.name);
                    uploadFiles(list);
                })
            }
            else {
                uploadFiles(list);
            }
        }
        uploadFiles(names);
    }
    else if(command.command === 'allFiles') {
        if(!command.dir) {
            slave.write(JSON.stringify(err.paraErr));
            return;
        }
        command.dir = command.dir.replace(/\,/g,'/');
        var fileNames = fs.readdirSync(path.resolve('./files'+command.dir));
        slave.write(JSON.stringify({
            names: fileNames
        }));
    }
    else if(command.command === 'videoDetail') {
        if(!command.dir || !command.name) {
            slave.write(JSON.stringify(err.paraErr));
            return;
        }
        command.dir = command.dir.replace(/\,/g,'/');
        var inputPath = path.resolve('./files'+command.dir+'/'+command.name);
        ffmpeg.ffprobe(inputPath, function (e, data) {
            if (e) {
                slave.write(JSON.stringify(err.paraErr));
                return;
            }
            slave.write(JSON.stringify({
                duration: data.streams[0].duration,
                tags: data.streams[0].tags
            }));
        });
    }
    else if(command.command === 'play') {
        if(!command.dir || !command.name) {
            slave.write(JSON.stringify(err.paraErr));
            return;
        }
        var channelName = command.name.split('.')[0];
        command.dir = command.dir.replace(/\,/g,'/');
        var input = path.resolve('./files'+command.dir+'/'+command.name);
        var output = 'rtmp://'+conf.tcpServerHost+':'+conf.rtmp+'/live/'+channelName;
        if(liveChannels.hasOwnProperty(channelName)) {
            slave.write(JSON.stringify({
                output: output,
                host: conf.tcpServerHost+':'+conf.rtmp,
                name: channelName
            }));
            return;
        }
        var state = fs.statSync(input);
        if(!state || state.isDirectory()){
            slave.write(JSON.stringify(err.fileNotExist));
            return;
        }
        var ffCommand = ffmpeg(input)
            .inputOptions('-re')
            .format('flv');
        if(command.seek) {
            ffCommand.seekInput(secToTime(command.seek));
        }
        if(command.scale) {
            ffCommand.size(Math.floor(command.scale*100) + '%');
        }
        ffCommand.on("start", function(commandLine){
            console.log('[' + new Date() + '] Command: ' + commandLine);
        })
        .on('error', function(err) {
            console.log('error: ' + err.message);
        })
        .on('end', function() {
            console.log('[' + new Date() + '] Vedio Pushing is Finished !');
        });
        ffCommand.output(output);
        ffCommand.run();
        liveChannels[channelName] = {
            command: ffCommand
        };
        slave.write(JSON.stringify({
            output: output,
            host: conf.tcpServerHost+':'+conf.rtmp,
            name: channelName
        }))
    }
    else if(command.command === 'stop') {
        if(!command.channelName) {
            slave.write(JSON.stringify(err.paraErr));
            return;
        }
        if(liveChannels.hasOwnProperty(command.channelName)) {
            liveChannels[command.channelName].command.kill();
            delete liveChannels[command.channelName];
            slave.write(liveChannels.hasOwnProperty(command.channelName).toString());
        }
    }
});
//监听与服务端连接的错误事件
slave.on('error',function (err) {
    console.log('在于服务器连接或通信过程中发生了一个错误，错误代码为%s', err.code);
    //当发生错误时，用destroy方法销毁该socket端口。确保不会再被利用
    setTimeout(getConnect, 10000);
});
getConnect();

//按照文件名判断文件类型
var fileType = function (name) {
    var suffix = name.split('.');
    suffix = suffix[suffix.length-1].toUpperCase();
    if(suffix === 'JPG'||suffix === 'PNG'||suffix === 'GIF'){
        return 'img'
    }else if(suffix === 'AVI'||suffix === 'MP4'||suffix === 'MKV'
        ||suffix === 'WMA'||suffix === 'RMVB'||suffix === 'RM'){
        return 'video'
    }else{
        return 'unknown'
    }
};
//字节数转容量
var byteToStr = function (size) {
    if(size/1000<1) return size.toFixed(2) + 'B';
    else if(size/1000000<1) return (size/1000).toFixed(2) + 'KB';
    else if(size/1000000000<1) return (size/1000000).toFixed(2) + 'MB';
    else return (size/1000000000).toFixed(2) + 'GB';
};
//时间转秒
var timeToSec = function(str) {
    var times = str.split(':');
    if(times.length !== 3) return null;
    return times[0]*3600 + times[1]*60 + times[2]*1;
};
var secToTime = function(sec){
    var h = Math.floor(sec/3600),
        m = Math.floor( (sec - h*3600) / 60),
        s = Math.floor(sec - h*3600 - m*60);
    h = h<10 ? '0'+h: h;
    m = m < 10 ? '0'+m : m;
    s = s < 10 ? '0'+s : s;
    return h + ':' + m + ':' + s;
};

